/**
 * 
 */
package com.cipe.cmrs.controllers.payment;

import java.sql.Timestamp;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import com.cipe.cmrs.bean.CodeDescriptionBean;
import com.cipe.cmrs.bean.PaymentRequestBean;
import com.cipe.cmrs.controllers.BaseController;
import com.cipe.cmrs.converter.DateEditor;
import com.cipe.cmrs.filter.SessionObjectFilter;
import com.cipe.cmrs.model.Country;
import com.cipe.cmrs.model.Payee;
import com.cipe.cmrs.model.Paymenttype;
import com.cipe.cmrs.model.User;
import com.cipe.cmrs.model.view.ProjectPaymentView;
import com.cipe.cmrs.service.AccountCodeService;
import com.cipe.cmrs.service.CipeprojectService;
import com.cipe.cmrs.service.CountryService;
import com.cipe.cmrs.service.PayeeService;
import com.cipe.cmrs.service.PaymentrequestService;
import com.cipe.cmrs.service.PaymenttypeService;
import com.cipe.cmrs.service.UserService;
import com.cipe.cmrs.util.Constants;
import com.cipe.cmrs.util.CustomTimestampEditor;
import com.cipe.cmrs.util.NumberUtil;

/**
 * @author Incepio
 * 
 */
public abstract class AbstractPaymentController extends BaseController {
    /**
	 * 
	 */
    private static final long serialVersionUID = 2071110718678373348L;
    protected static final String COMMAND_NAME = "paymentrequest";
    @Autowired
    protected PaymentrequestService paymentrequestService;
    @Autowired
    protected CountryService countryService;
    @Autowired
    protected PaymenttypeService paymenttypeService;
    @Autowired
    protected UserService userService;
    @Autowired
    protected PayeeService payeeService;
    @Autowired
    protected CipeprojectService cipeprojectService;
    @Autowired
    protected AccountCodeService accountCodeService;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Timestamp.class, new CustomTimestampEditor(Constants.DefaultDateFormat));
        binder.registerCustomEditor(java.util.Date.class, new DateEditor(Constants.DefaultDateFormat, Constants.DefaultDateFormat));
    }

    @RequestMapping(method = RequestMethod.GET)
    protected ModelAndView getFormView(@ModelAttribute(COMMAND_NAME) PaymentRequestBean bean, HttpServletRequest request) {
        ModelAndView mav = new ModelAndView(getFormView());
        PaymentRequestBean unsavedPayment = (PaymentRequestBean) request.getSession().getAttribute(SessionObjectFilter.UNSAVED_PAYMENT);
        if (unsavedPayment != null) {
            bean = unsavedPayment;
            mav.addObject(COMMAND_NAME, bean);
        }

        String payeeIdParam = (String) request.getParameter("payeeId");
        if (StringUtils.hasText(payeeIdParam) && NumberUtil.INSTANCE.isInteger(payeeIdParam)) {
            Integer payeeId = Integer.valueOf(payeeIdParam);
            if (payeeId > 0) {
                bean.setPayeeId(payeeId);
            }
        }
        return mav.addAllObjects(getReferenceData(bean, request));
    }

    protected ModelAndView getSuccessView(PaymentRequestBean paymentRequest, HttpServletRequest request) {
        return new ModelAndView(getSuccessView()).addAllObjects(getReferenceData(paymentRequest, request));
    }

    protected abstract ModelAndView onSubmit(@ModelAttribute(COMMAND_NAME) PaymentRequestBean bean, BindingResult result,
        HttpServletRequest request, SessionStatus status);

    protected Map<String, Object> getReferenceData(PaymentRequestBean paymentRequest, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("cipeProjects", getAllCipeProjects(paymentRequest.getId()));
        map.put("accountCodes", getAllAccountCodes());
        map.put("currentUserId", getUserId(request));
        map.put("countryList", getAllCountries());
        map.put("userList", getAllUsers());
        map.put("payeeList", getAllPayees(paymentRequest));
        map.put("paymenttypeList", getActivePaymentTypes(paymentRequest));
        return map;
    }

    public List<ProjectPaymentView> getAllCipeProjects(Integer excludePaymentRequest) {
        return cipeprojectService.getAllActiveCipeProjects(excludePaymentRequest);
    }

    public List<CodeDescriptionBean> getAllAccountCodes() {
        return accountCodeService.getAllAccountCodeBeans(Arrays.asList("id", "accountCode", "description", "accountStatus"));
    }

    public Integer getUserId(HttpServletRequest request) {
        return getUserId(request.getSession());
    }

    public List<Country> getAllCountries() {
        return countryService.getAllCountries();
    }

    public List<Paymenttype> getActivePaymentTypes(PaymentRequestBean bean) {
        return paymenttypeService.getActivePaymentTypes(bean.getPaymentTypeId());
    }

    public List<User> getAllUsers() {
        return userService.findAll();
    }

    public List<Payee> getAllPayees(PaymentRequestBean paymentRequest) {
        return payeeService.getAllActivePayees(paymentRequest.getPayeeId());
    }

}
